/****************************************************************************
 *
 *  ALi (Shanghai) Corporation, All Rights Reserved. 2007 Copyright (C)
 *
 *  File: pvr_mgr_user_data.c
 *
 *  Description: This file describes pvr user data functions.
 *
 *  History:
 *      Date        	Author      	Version  		Comment
 *      ====        	======      	=======  		=======
 *  1.  2009.3.20  		Dukula_Zhu  	0.0.1  		
 *
 ****************************************************************************/
#include "pvr_mgr_data.h"

void printf_user_data(char *func, void *buffer)
{
	ppvr_mgr_user_data user = (ppvr_mgr_user_data)buffer;
	UINT8 i;
	
	libc_printf("%s, subt_num = %d\n", func, user->subt_num);

	for( i = 0; i < user->subt_num; i++)
	{
		char eng_lang[10];
		MEMSET(eng_lang, 0, sizeof(eng_lang));
		MEMCPY(eng_lang, user->subt_array[i].lang, 3);
		libc_printf("subt[%d] = %d\n", i, user->subt_array[i].pid, eng_lang);
	}
}

RET_CODE _pvr_mgr_bookmark_set(ppvr_mgr_list_item record_item, UINT32 mark_time)
{
	RET_CODE ret = RET_SUCCESS;
	ppvr_mgr_active_record record = NULL;
	BOOL need_malloc = FALSE;
	struct list_head *ptr = NULL;
	pbookmark_list_item mark_list_item = NULL, temp_item = NULL;
	UINT16 i;
	UINT32 left_ptm, right_ptm, len;
	BOOL delete_bookmark = FALSE;
	BOOL add_bookmark = FALSE;

	pvr_return_val_if_fail(((record_item != NULL) && (record_item->record_info != NULL) && (mark_time > 0)), RET_FAILURE);

	record = _pvr_get_record_bypath(record_item->record_dir_path);
	if((record != NULL) && (record->r_handle != 0))
	{
		REC_ENG_INFO item_info;
		pvr_eng_get_record_info(0, record_item->record_dir_path, &item_info);
		_pvr_list_trans_eng_info(&record_item->record_info->record, &item_info);
	}
	if(mark_time > record_item->record_info->record.duration)
	{
		PDEBUG("mark_time(%d) > duration(%d)\n", mark_time, record_item->record_info->record.duration);
		return ret;
	}
		
	// get the left and right scope
	left_ptm = (mark_time * 1000 < BOOKMARK_THRESHOLD_TIME) ? record_item->record_info->record.start_ptm: (mark_time * 1000 - BOOKMARK_THRESHOLD_TIME + record_item->record_info->record.start_ptm);
	right_ptm = mark_time * 1000 + BOOKMARK_THRESHOLD_TIME + record_item->record_info->record.start_ptm;
	PDEBUG("mark_time=%d, left_time=%d, right_time=%d\n",mark_time, (left_ptm - record_item->record_info->record.start_ptm)/1000, (right_ptm - record_item->record_info->record.start_ptm)/1000);

	if(record_item->record_info->puser_data == NULL)
	{
		need_malloc = TRUE;
		_pvr_mgr_malloc(record_item->record_info->puser_data, sizeof(pvr_mgr_user_data), 1);
		pvr_eng_get_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, &len);
	}
	
	// find it at bookmark_list, if found, delete this bookmark.
	list_for_each(ptr, &record->bookmark_list)
	{
		temp_item = list_entry(ptr, bookmark_list_item, listpointer);
		UINT32 item_ptm = temp_item->item.ptm;

		if((item_ptm < right_ptm)  && (item_ptm > left_ptm))
		{
			// new bookmark has been found at bk_list, delete it.
			list_del(&temp_item->listpointer);
			record_item->record_info->puser_data->bookmark_num--;
			delete_bookmark = TRUE;
			PDEBUG("del bookmark time=%d, now num=%d\n", (item_ptm - record_item->record_info->record.start_ptm)/1000, record_item->record_info->puser_data->bookmark_num);
			break;
		}
	}

	// not found this bookmark, add it.
	if(!delete_bookmark)
	{
		if(record_item->record_info->puser_data->bookmark_num >= MAX_BOOKMARK_NUM)
		{
			PDEBUG("too many bookmark %d\n", record_item->record_info->puser_data->bookmark_num);
			return RET_FAILURE;
		}
		_pvr_mgr_malloc(temp_item, sizeof(bookmark_list_item), 1);
		temp_item->item.ptm = mark_time * 1000 + record_item->record_info->record.start_ptm;

		if(list_empty(&record->bookmark_list))
		{
			// add to the list tail
			list_add_tail(&temp_item->listpointer, &record->bookmark_list);
		}
		else
		{
			// find the new bookmark insert position.
			list_for_each(ptr, &record->bookmark_list)
			{
				mark_list_item = list_entry(ptr, bookmark_list_item, listpointer);
				if(mark_list_item->item.ptm > right_ptm)
				{
					mark_list_item = (pbookmark_list_item)ptr->prev;
					break;
				}
			}
			list_add(&temp_item->listpointer, &mark_list_item->listpointer);
		}
		record_item->record_info->puser_data->bookmark_num++;
		PDEBUG("add bookmark mark_time=%ds, now num=%d\n", mark_time, record_item->record_info->puser_data->bookmark_num);
		add_bookmark = TRUE;
	}

	if(delete_bookmark || add_bookmark)
	{
		i = 0;
		list_for_each(ptr, &record->bookmark_list)
		{
			mark_list_item = list_entry(ptr, bookmark_list_item, listpointer);
			record_item->record_info->puser_data->bookmark_array[i].ptm = mark_list_item->item.ptm;
			i++;
		}
		ASSERT(i == record_item->record_info->puser_data->bookmark_num);
		ret = pvr_eng_set_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, sizeof(pvr_mgr_user_data));
		PDEBUG("record %d, save bookmark %d\n", record_item->record_info->record_idx, record_item->record_info->puser_data->bookmark_num);
	}

	if(need_malloc)
		_pvr_mgr_free(record_item->record_info->puser_data);
	
	return RET_SUCCESS;
}

UINT8 _pvr_mgr_bookmark_get(ppvr_mgr_list_item record_item, UINT32 *mark_ptm_array)
{
	UINT16 i, bookmark_num;
	BOOL need_malloc = FALSE;
	UINT32 len;
	BOOL save = FALSE;
	
	pvr_return_val_if_fail((record_item != NULL), 0);

	if(record_item->record_info->puser_data == NULL)
	{
		need_malloc = TRUE;
		_pvr_mgr_malloc(record_item->record_info->puser_data, sizeof(pvr_mgr_user_data), 1);
		pvr_eng_get_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, &len);
	}

	bookmark_num = record_item->record_info->puser_data->bookmark_num;
	for(i=0; i<bookmark_num; i++)
	{
		if(record_item->record_info->puser_data->bookmark_array[i].ptm <= record_item->record_info->record.start_ptm)
		{
			record_item->record_info->puser_data->bookmark_num--;
			save = TRUE;
			PDEBUG("invalid bookmark %d\n", i+1);
		}
		else
		{
			mark_ptm_array[i] = (record_item->record_info->puser_data->bookmark_array[i].ptm - record_item->record_info->record.start_ptm) / 1000;
			PDEBUG("\tmark %d, mark_time=%d\n", i+1, mark_ptm_array[i]);
		}
	}
	//PDEBUG("there are %d bookmarks!\n", record_item->record_info->puser_data->bookmark_num);

	if(save)
	{
		pvr_eng_set_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, sizeof(pvr_mgr_user_data));
	}
	if(need_malloc)
		_pvr_mgr_free(record_item->record_info->puser_data);
	
	return record_item->record_info->puser_data->bookmark_num;
}

void _pvr_mgr_bookmark_dellist(ppvr_mgr_active_record record)
{
	pbookmark_list_item mark_list_item = NULL;
	struct list_head *ptr = NULL, *ptn = NULL;
	
	//clear bookmark info in ram
	if(!list_empty(&record->bookmark_list))
	{
		list_for_each_safe(ptr, ptn, &record->bookmark_list)
		{
			mark_list_item = list_entry(ptr, bookmark_list_item, listpointer);
			list_del(ptr);
			_pvr_mgr_free(mark_list_item);
		}
		INIT_LIST_HEAD(&record->bookmark_list);
	}
}

void _pvr_mgr_bookmark_load(ppvr_mgr_list_item record_item)
{
	ppvr_mgr_active_record record = NULL;
	BOOL need_malloc = FALSE;
	struct list_head *ptr = NULL;
	pbookmark_list_item mark_list_item = NULL;
	UINT16 i;
	UINT32 len;

	record = _pvr_get_record_bypath(record_item->record_dir_path);
	if((record != NULL) && (record->r_handle != 0))
	{
		REC_ENG_INFO item_info;
		pvr_eng_get_record_info(0, record_item->record_dir_path, &item_info);
		_pvr_list_trans_eng_info(&record_item->record_info->record, &item_info);
	}
	
	if(record_item->record_info->puser_data == NULL)
	{
		need_malloc = TRUE;
		_pvr_mgr_malloc(record_item->record_info->puser_data, sizeof(pvr_mgr_user_data), 1);
		pvr_eng_get_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, &len);
	}
	
	//TODO:load bookmark
	INIT_LIST_HEAD(&record->bookmark_list);
	if(record_item->record_info->puser_data->bookmark_num)
	{
		
		for(i=0; i<record_item->record_info->puser_data->bookmark_num; i++)
		{
			_pvr_mgr_malloc(mark_list_item, sizeof(bookmark_list_item), 1);
			if(record_item->record_info->puser_data->bookmark_array[i].ptm <= record_item->record_info->record.start_ptm)
			{
				PDEBUG("invalid bookmark %d\n", i+1);
			}
			else
			{
				MEMCPY(&mark_list_item->item, &record_item->record_info->puser_data->bookmark_array[i], sizeof(record_bookmark_item));
				list_add_tail(&mark_list_item->listpointer, &record->bookmark_list);
			}
		}
	}

	if(need_malloc)
		_pvr_mgr_free(record_item->record_info->puser_data);
}

RET_CODE _pvr_mgr_repeatmark_set(ppvr_mgr_list_item record_item, UINT32 mark_time)
{
	RET_CODE ret = RET_SUCCESS;
	ppvr_mgr_active_record record = NULL;
	BOOL need_malloc = FALSE;
	struct list_head *ptr = NULL;
	pbookmark_list_item mark_list_item = NULL, temp_item = NULL;
	UINT16 i;
	UINT32 cur_pos, len;

	pvr_return_val_if_fail(((record_item != NULL) && (record_item->record_info != NULL) && (mark_time > 0)), RET_FAILURE);

	record = _pvr_get_record_bypath(record_item->record_dir_path);
	if((record != NULL) && (record->r_handle != 0))
	{
		REC_ENG_INFO item_info;
		pvr_eng_get_record_info(0, record_item->record_dir_path, &item_info);
		_pvr_list_trans_eng_info(&record_item->record_info->record, &item_info);
	}

	if(mark_time == (UINT32)(-1))
	{
		REC_ENG_INFO item_info;
		
		PDEBUG("clear repeat AB mark\n");
		//clear reapeat AB
		record_item->record_info->puser_data->repeat_AB = 0;
		MEMSET(record_item->record_info->puser_data->AB_array, 0, 2 * sizeof(record_bookmark_item));

		pvr_eng_get_record_info(0, record_item->record_dir_path, &item_info);
		item_info.se_info.stat_end_grp_num = 0;
		item_info.se_info.start_end_state = 0;
		item_info.se_info.start_end[item_info.se_info.start_end_state/2][0] = 0;
		item_info.se_info.start_end[item_info.se_info.start_end_state/2][1] = 0;
		pvr_eng_set_record_info(record->p_handle, record_item->record_dir_path, &item_info);
		return RET_SUCCESS;
	}

	if(mark_time > record_item->record_info->record.duration)
	{
		PDEBUG("mark_time(%d) > duration(%d)\n", mark_time, record_item->record_info->record.duration);
		return ret;
	}
		
	if(record_item->record_info->puser_data == NULL)
	{
		need_malloc = TRUE;
		_pvr_mgr_malloc(record_item->record_info->puser_data, sizeof(pvr_mgr_user_data), 1);
		pvr_eng_get_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, &len);
	}

	pvr_eng_ioctl(record->p_handle, PVR_EPIO_GET_POS, (UINT32)&cur_pos, 0);	

	record_item->record_info->puser_data->AB_array[record_item->record_info->puser_data->repeat_AB].ptm = mark_time * 1000 + record_item->record_info->record.start_ptm;
	record_item->record_info->puser_data->AB_array[record_item->record_info->puser_data->repeat_AB].file_idx = PLAY_FILE_IDX(cur_pos);
	record_item->record_info->puser_data->AB_array[record_item->record_info->puser_data->repeat_AB].vobu_idx = PLAY_VOBU_IDX(cur_pos);

	record_item->record_info->puser_data->repeat_AB++;
	if((record_item->record_info->puser_data->repeat_AB == 2) && (record_item->record_info->puser_data->AB_array[0].ptm > record_item->record_info->puser_data->AB_array[1].ptm))
	{
		record_bookmark_item temp_mark;
		MEMCPY(&temp_mark, &record_item->record_info->puser_data->AB_array[0], sizeof(record_bookmark_item));
		MEMCPY(&record_item->record_info->puser_data->AB_array[0], &record_item->record_info->puser_data->AB_array[1], sizeof(record_bookmark_item));
		MEMCPY(&record_item->record_info->puser_data->AB_array[1], &temp_mark, sizeof(record_bookmark_item));
	}

	if(record_item->record_info->puser_data->repeat_AB == 2)
	{
		REC_ENG_INFO item_info;
		pvr_eng_get_record_info(0, record_item->record_dir_path, &item_info);
		item_info.se_info.stat_end_grp_num = 1;
		item_info.se_info.start_end_state = 1;
		item_info.se_info.start_end[item_info.se_info.start_end_state/2][0] = PLAY_POS(record_item->record_info->puser_data->AB_array[0].file_idx, record_item->record_info->puser_data->AB_array[0].vobu_idx);
		item_info.se_info.start_end[item_info.se_info.start_end_state/2][1] = PLAY_POS(record_item->record_info->puser_data->AB_array[1].file_idx, record_item->record_info->puser_data->AB_array[1].vobu_idx);
		pvr_eng_set_record_info(record->p_handle, record_item->record_dir_path, &item_info);
	}

	if(need_malloc)
		_pvr_mgr_free(record_item->record_info->puser_data);
	
	return RET_SUCCESS;
}

UINT8 _pvr_mgr_repeatmark_get(ppvr_mgr_list_item record_item, UINT32 *mark_ptm_array)
{
	UINT16 i, bookmark_num;
	BOOL need_malloc = FALSE;
	UINT32 len;
	BOOL save = FALSE;
	
	pvr_return_val_if_fail((record_item != NULL), 0);

	if(record_item->record_info->puser_data == NULL)
	{
		need_malloc = TRUE;
		_pvr_mgr_malloc(record_item->record_info->puser_data, sizeof(pvr_mgr_user_data), 1);
		pvr_eng_get_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, &len);
	}
	
	mark_ptm_array[0] = (record_item->record_info->puser_data->AB_array[0].ptm - record_item->record_info->record.start_ptm) / 1000;
	mark_ptm_array[1] = (record_item->record_info->puser_data->AB_array[1].ptm - record_item->record_info->record.start_ptm) / 1000;
	
	if(need_malloc)
		_pvr_mgr_free(record_item->record_info->puser_data);
	
	return record_item->record_info->puser_data->repeat_AB;
}


void _pvr_mgr_save_cur_pos(PVR_HANDLE handle)
{
	UINT32 pos, ptm;
	ppvr_mgr_list_item record_item = NULL;
	ppvr_mgr_active_record record = NULL;
	
	pvr_eng_ioctl(handle, PVR_EPIO_GET_POS, (UINT32)&pos, 0);	
	pvr_eng_ioctl(handle, PVR_EPIO_GET_TIME, (UINT32)&ptm, 0);	
	record = _pvr_get_record_byhandle(handle);
	pvr_return_if_fail(record != NULL);

	record_item = list_entry(record->listpointer, pvr_mgr_list_item, listpointer);
	pvr_return_if_fail(record_item != NULL);

	record_item->record_info->puser_data->last_play_pos = pos;
	record_item->record_info->puser_data->last_play_ptm = ptm;
	pvr_eng_set_user_data(handle, NULL, record_item->record_info->puser_data, sizeof(pvr_mgr_user_data));
}

UINT32 _pvr_mgr_get_last_pos(ppvr_mgr_list_item record_item)
{
	UINT32 ret = 0;
	BOOL need_malloc = FALSE;
	UINT32 len;
	
	if(record_item->record_info->puser_data == NULL)
	{
		need_malloc = TRUE;
		_pvr_mgr_malloc(record_item->record_info->puser_data, sizeof(pvr_mgr_user_data), 1);
		pvr_eng_get_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, &len);
	}

	ret = record_item->record_info->puser_data->last_play_pos;

	if(need_malloc)
		_pvr_mgr_free(record_item->record_info->puser_data);

	return ret;
}

UINT32 _pvr_mgr_get_last_posptm(ppvr_mgr_list_item record_item)
{
	UINT32 ret = 0;
	BOOL need_malloc = FALSE;
	UINT32 len;
	
	if(record_item->record_info->puser_data == NULL)
	{
		need_malloc = TRUE;
		_pvr_mgr_malloc(record_item->record_info->puser_data, sizeof(pvr_mgr_user_data), 1);
		pvr_eng_get_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, &len);
	}

	ret = record_item->record_info->puser_data->last_play_ptm;
	if((ret + 5) >= record_item->record_info->record.duration)
	{
		ret = 0;
	}
	
	if(need_malloc)
		_pvr_mgr_free(record_item->record_info->puser_data);

	return ret;
}



RET_CODE _pvr_mgr_agelimit_set(ppvr_mgr_list_item record_item, UINT32 ptm, UINT32 age)
{
	RET_CODE ret = RET_SUCCESS;
    BOOL add_agelimit = FALSE;
 	ppvr_mgr_active_record record = NULL;
	BOOL need_malloc = FALSE;
 	UINT32 len;
  
	pvr_return_val_if_fail(((record_item != NULL) && (record_item->record_info != NULL)), RET_FAILURE);

	record = _pvr_get_record_bypath(record_item->record_dir_path);
	if((record != NULL) && (record->r_handle != 0))
	{
		REC_ENG_INFO item_info;
		pvr_eng_get_record_info(0, record_item->record_dir_path, &item_info);
		_pvr_list_trans_eng_info(&record_item->record_info->record, &item_info);
	}
	
	if(record_item->record_info->puser_data == NULL)
	{
		need_malloc = TRUE;
		_pvr_mgr_malloc(record_item->record_info->puser_data, sizeof(pvr_mgr_user_data), 1);
		pvr_eng_get_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, &len);
	}

	if(record_item->record_info->puser_data->agelimit_num >= MAX_AGELIMIT_NUM-1)
	{
		PDEBUG("too many agelimit\n");
		return RET_FAILURE;
	}

    if((record_item->record_info->puser_data->agelimit_num == 0) && (record_item->record_info->puser_data->agelimit_array[0].age != age))
    {
         record_item->record_info->puser_data->agelimit_array[0].age = age;
         record_item->record_info->puser_data->agelimit_array[0].ptm = ptm; 
         add_agelimit = TRUE;
         record_item->record_info->puser_data->agelimit_num++;
    }
    else if((record_item->record_info->puser_data->agelimit_num > 0)
        && (record_item->record_info->puser_data->agelimit_array[record_item->record_info->puser_data->agelimit_num-1].age != age)
        && (record_item->record_info->puser_data->agelimit_array[record_item->record_info->puser_data->agelimit_num-1].ptm < ptm))
    {
        record_item->record_info->puser_data->agelimit_array[record_item->record_info->puser_data->agelimit_num-1].ptm = ptm - 1;
        record_item->record_info->puser_data->agelimit_array[record_item->record_info->puser_data->agelimit_num].age = age;
        record_item->record_info->puser_data->agelimit_array[record_item->record_info->puser_data->agelimit_num].ptm = ptm; 
	    add_agelimit = TRUE;
        record_item->record_info->puser_data->agelimit_num++;
    }		
		
	if(add_agelimit)
	{
        PDEBUG("agelimit num=%d, ptm=%d, age=%d\n", record_item->record_info->puser_data->agelimit_num,ptm, age);
		ret = pvr_eng_set_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, sizeof(pvr_mgr_user_data));
		PDEBUG("record %d, save agelimit %d\n", record_item->record_info->record_idx, record_item->record_info->puser_data->agelimit_num);
	}

	if(need_malloc)
		_pvr_mgr_free(record_item->record_info->puser_data);
	
	return ret;
}

UINT8 _pvr_mgr_agelimit_get(ppvr_mgr_list_item record_item, UINT32 ptm)
{
	UINT8 ret = 0;
	UINT16 i;
 	ppvr_mgr_active_record record = NULL;
	BOOL need_malloc = FALSE;
	UINT32 len;
	
	pvr_return_val_if_fail(((record_item != NULL) && (record_item->record_info != NULL)), 0);

	if(record_item->record_info->puser_data == NULL)
	{
		need_malloc = TRUE;
		_pvr_mgr_malloc(record_item->record_info->puser_data, sizeof(pvr_mgr_user_data), 1);
		pvr_eng_get_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, &len);
	}

    if(record_item->record_info->puser_data->agelimit_num==0)
        return ret;

	for(i=0; i<record_item->record_info->puser_data->agelimit_num; i++)
	{
        if(i+1 < record_item->record_info->puser_data->agelimit_num)
        {
            if((record_item->record_info->puser_data->agelimit_array[i].ptm < ptm) && (record_item->record_info->puser_data->agelimit_array[i+1].ptm >= ptm))
                ret = record_item->record_info->puser_data->agelimit_array[i+1].age;
            else if(record_item->record_info->puser_data->agelimit_array[i].ptm >= ptm)
                ret = record_item->record_info->puser_data->agelimit_array[i].age;
        }
        else
        {
            //if((record_item->record_info->puser_data->agelimit_array[i].ptm<ptm))
            //    return 0;
            //else
                ret = record_item->record_info->puser_data->agelimit_array[i].age;//if not find age, get the lateset age
        }
	}
  
	if(need_malloc)
		_pvr_mgr_free(record_item->record_info->puser_data);
  	
	return ret;
}



RET_CODE _pvr_mgr_ratingctl_set(ppvr_mgr_list_item record_item, UINT32 ptm, UINT32 ratingctl)
{
	RET_CODE ret = RET_SUCCESS;
	BOOL add_ratingctl = FALSE;
 	ppvr_mgr_active_record record = NULL;
	BOOL need_malloc = FALSE;
	UINT32 len;
   
	pvr_return_val_if_fail(((record_item != NULL) && (record_item->record_info != NULL)), RET_FAILURE);

	record = _pvr_get_record_bypath(record_item->record_dir_path);
	if((record != NULL) && (record->r_handle != 0))
	{
		REC_ENG_INFO item_info;
		pvr_eng_get_record_info(0, record_item->record_dir_path, &item_info);
		_pvr_list_trans_eng_info(&record_item->record_info->record, &item_info);
	}
	
	if(record_item->record_info->puser_data == NULL)
	{
		need_malloc = TRUE;
		_pvr_mgr_malloc(record_item->record_info->puser_data, sizeof(pvr_mgr_user_data), 1);
		pvr_eng_get_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, &len);
	}

	if(record_item->record_info->puser_data->ratingctl_num >= MAX_RATINGCTL_NUM-1)
	{
		PDEBUG("too many ratingctl\n");
		return RET_FAILURE;
	}

	if((record_item->record_info->puser_data->ratingctl_num == 0) && (record_item->record_info->puser_data->ratingctl_array[0].rating != ratingctl))
	{
		record_item->record_info->puser_data->ratingctl_array[0].rating = ratingctl;
		record_item->record_info->puser_data->ratingctl_array[0].ptm = ptm; 
		record_item->record_info->puser_data->ratingctl_num++;
		add_ratingctl = TRUE;
	}
	else if((record_item->record_info->puser_data->ratingctl_num>0)
		&& (record_item->record_info->puser_data->ratingctl_array[record_item->record_info->puser_data->ratingctl_num-1].rating != ratingctl)
		&& (record_item->record_info->puser_data->ratingctl_array[record_item->record_info->puser_data->ratingctl_num-1].ptm < ptm))
	{
		//record_item->record_info->puser_data->ratingctl_array[record_item->record_info->puser_data->ratingctl_num-1].ptm = ptm-1;
		record_item->record_info->puser_data->ratingctl_array[record_item->record_info->puser_data->ratingctl_num].rating = ratingctl;
		record_item->record_info->puser_data->ratingctl_array[record_item->record_info->puser_data->ratingctl_num].ptm = ptm; 
		record_item->record_info->puser_data->ratingctl_num++;
		add_ratingctl = TRUE;
	}		
		
	if(add_ratingctl)
	{
		PDEBUG("ratingctl num=%d, ptm=%d, rating =%d\n",record_item->record_info->puser_data->ratingctl_num,ptm, ratingctl);
		ret = pvr_eng_set_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, sizeof(pvr_mgr_user_data));
		PDEBUG("record %d, save ratingctl %d\n", record_item->record_info->record_idx, record_item->record_info->puser_data->ratingctl_num);
	}
	
	if(need_malloc)
		_pvr_mgr_free(record_item->record_info->puser_data);

	return ret;
}

// for ATSC rating get
UINT32 _pvr_mgr_ratingctl_get(ppvr_mgr_list_item record_item, UINT32 ptm)
{
	UINT8 ret = 0;
	UINT16 i;
 	ppvr_mgr_active_record record = NULL;
	BOOL need_malloc = FALSE;
	UINT32 len;
	
	pvr_return_val_if_fail(((record_item != NULL) && (record_item->record_info != NULL)), 0);

	if(record_item->record_info->puser_data == NULL)
	{
		need_malloc = TRUE;
		_pvr_mgr_malloc(record_item->record_info->puser_data, sizeof(pvr_mgr_user_data), 1);
		pvr_eng_get_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, &len);
	}

	if(record_item->record_info->puser_data->ratingctl_num==0)
		return 0;

	for(i=0; i<record_item->record_info->puser_data->ratingctl_num; i++)
	{
		if(i+1<record_item->record_info->puser_data->ratingctl_num)
		{
			if((record_item->record_info->puser_data->ratingctl_array[i].ptm<=ptm)&&(record_item->record_info->puser_data->ratingctl_array[i+1].ptm>ptm))
				ret = record_item->record_info->puser_data->ratingctl_array[i].rating;
			else if(record_item->record_info->puser_data->ratingctl_array[i].ptm>=ptm)
				ret = 0;
		}
		else
		{
			if(record_item->record_info->puser_data->ratingctl_array[i].ptm>=ptm)
				ret = 0;
			else
				ret = record_item->record_info->puser_data->ratingctl_array[i].rating;//if not find age, get the lateset age
		}
	}
  
	if(need_malloc)
		_pvr_mgr_free(record_item->record_info->puser_data);
  	
	return ret;
}

// DTG_PVR : event detail
RET_CODE _pvr_data_set_event_detail(ppvr_mgr_list_item record_item, UINT8 *pDetail, UINT32 len, UINT8 type)
{
	RET_CODE ret = RET_SUCCESS;
 	ppvr_mgr_active_record record = NULL;
	BOOL need_malloc = FALSE;
	UINT32 user_data_len;
	
	pvr_return_val_if_fail(((record_item != NULL) && (record_item->record_info != NULL)), RET_FAILURE);

	record = _pvr_get_record_bypath(record_item->record_dir_path);
	
	if((record != NULL) && (record->r_handle != 0))
	{
		REC_ENG_INFO item_info;
		pvr_eng_get_record_info(0, record_item->record_dir_path, &item_info);
		_pvr_list_trans_eng_info(&record_item->record_info->record, &item_info);
	}
	
	if(record_item->record_info->puser_data == NULL)
	{
		need_malloc = TRUE;
		_pvr_mgr_malloc(record_item->record_info->puser_data, sizeof(pvr_mgr_user_data), 1);
		pvr_eng_get_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, &user_data_len);
	}

	len = len >EVENT_DETAIL_MAX_LEN? EVENT_DETAIL_MAX_LEN:len;

	ASSERT(type == SHORT_DETAIL | type == EXTEND_DETAIL);

	if(type == SHORT_DETAIL)
		MEMCPY(record_item->record_info->puser_data->event_short_detail, (UINT8 *)pDetail, len);
	else
		MEMCPY(record_item->record_info->puser_data->event_ext_detail, (UINT8 *)pDetail, len);

	ret = pvr_eng_set_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, sizeof(pvr_mgr_user_data));

	if(need_malloc)
		_pvr_mgr_free(record_item->record_info->puser_data);
	
	return ret;
}

UINT8* _pvr_data_get_event_detail(ppvr_mgr_list_item record_item, UINT8 type)
{
 	ppvr_mgr_active_record record = NULL;
	BOOL need_malloc = FALSE;
	UINT32 len;
	UINT8* ret;

	pvr_return_val_if_fail(((record_item != NULL) && (record_item->record_info != NULL)), 0);
	
	if(record_item->record_info->puser_data == NULL)
	{
		// puser_data is NULL, might need a static buffer to hold the event detal and return it
		PDEBUG("Invalid pointer to user_data!\n");
		return NULL;
		/*
		need_malloc = TRUE;
		_pvr_mgr_malloc(record_item->record_info->puser_data, sizeof(pvr_mgr_user_data), 1);
		pvr_eng_get_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, &len);
		*/
	}

	ASSERT(type == SHORT_DETAIL | type == EXTEND_DETAIL);

	if(type == SHORT_DETAIL)
		ret = record_item->record_info->puser_data->event_short_detail;
	else
		ret = record_item->record_info->puser_data->event_ext_detail;

	/*
	if(need_malloc)
		_pvr_mgr_free(record_item->record_info->puser_data);
	*/

	return ret;	
}
// DTG_PVR : event name
RET_CODE _pvr_data_set_event_name(ppvr_mgr_list_item record_item, UINT8* event_name)
{
	RET_CODE ret = RET_SUCCESS;
	ppvr_mgr_active_record record = NULL;
	BOOL need_malloc = FALSE;
	UINT32 len;

	pvr_return_val_if_fail(((record_item != NULL) && (record_item->record_info != NULL)), RET_FAILURE);

	record = _pvr_get_record_bypath(record_item->record_dir_path);
	
	if((record != NULL) && (record->r_handle != 0))
	{
		REC_ENG_INFO item_info;
		pvr_eng_get_record_info(0, record_item->record_dir_path, &item_info);
		_pvr_list_trans_eng_info(&record_item->record_info->record, &item_info);
	}
	
	if(record_item->record_info->puser_data == NULL)
	{
		need_malloc = TRUE;
		_pvr_mgr_malloc(record_item->record_info->puser_data, sizeof(pvr_mgr_user_data), 1);
		pvr_eng_get_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, &len);
	}

	MEMCPY(record_item->record_info->puser_data->event_name, (UINT8 *)event_name, EVENT_NAME_MAX_LEN);
	
	ret = pvr_eng_set_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, sizeof(pvr_mgr_user_data));
	MEMCPY(record_item->record_info->record.event_txti, event_name, EVENT_NAME_MAX_LEN);

	if(need_malloc)
		_pvr_mgr_free(record_item->record_info->puser_data);
	
	return ret;
}

UINT8* _pvr_data_get_event_name(ppvr_mgr_list_item record_item)
{
	ppvr_mgr_active_record record = NULL;
	BOOL need_malloc = FALSE;
	UINT32 len;
	UINT8* ret;

	pvr_return_val_if_fail(((record_item != NULL) && (record_item->record_info != NULL)), 0);
	
	if(record_item->record_info->puser_data == NULL)
	{
		// puser_data is NULL, might need a static buffer to hold the event name and return it
		PDEBUG("Invalid pointer to user_data!\n");
		return NULL;
		/*
		need_malloc = TRUE;
		_pvr_mgr_malloc(record_item->record_info->puser_data, sizeof(pvr_mgr_user_data), 1);
		pvr_eng_get_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, &len);
		*/
	}

	ret = record_item->record_info->puser_data->event_name;

	/*
	if(need_malloc)
		_pvr_mgr_free(record_item->record_info->puser_data);
	*/
	return ret;
}


RET_CODE _pvr_mgr_audio_type_set(ppvr_mgr_list_item record_item, UINT8 *buf, UINT8 len)
{
	RET_CODE ret = RET_SUCCESS;
 	ppvr_mgr_active_record record = NULL;
	BOOL need_malloc = FALSE;
	UINT32 user_data_len;
   
	pvr_return_val_if_fail(((record_item != NULL) && (record_item->record_info != NULL)), RET_FAILURE);

	record = _pvr_get_record_bypath(record_item->record_dir_path);
	if((record != NULL) && (record->r_handle != 0))
	{
		REC_ENG_INFO item_info;
		pvr_eng_get_record_info(0, record_item->record_dir_path, &item_info);
		_pvr_list_trans_eng_info(&record_item->record_info->record, &item_info);
	}
	
	if(record_item->record_info->puser_data == NULL)
	{
		need_malloc = TRUE;
		_pvr_mgr_malloc(record_item->record_info->puser_data, sizeof(pvr_mgr_user_data), 1);
		pvr_eng_get_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, &user_data_len);
	}

	MEMSET(record_item->record_info->puser_data->multi_audio_type, 0, MAX_PVR_AUDIO_PID);
	MEMCPY(record_item->record_info->puser_data->multi_audio_type, buf,
		((len < MAX_PVR_AUDIO_PID) ? len : MAX_PVR_AUDIO_PID));

	ret = pvr_eng_set_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, sizeof(pvr_mgr_user_data));
	
	if(need_malloc)
		_pvr_mgr_free(record_item->record_info->puser_data);

	return ret;
}

RET_CODE _pvr_mgr_audio_type_get(ppvr_mgr_list_item record_item, UINT8 *buf, UINT8 len)
{
	UINT8 ret = RET_SUCCESS;
 	ppvr_mgr_active_record record = NULL;
	BOOL need_malloc = FALSE;
	UINT32 user_data_len;
	
	pvr_return_val_if_fail(((record_item != NULL) && (record_item->record_info != NULL)), RET_FAILURE);

	if(record_item->record_info->puser_data == NULL)
	{
		need_malloc = TRUE;
		_pvr_mgr_malloc(record_item->record_info->puser_data, sizeof(pvr_mgr_user_data), 1);
		pvr_eng_get_user_data(0, record_item->record_dir_path, record_item->record_info->puser_data, &user_data_len);
	}

	MEMCPY(buf, record_item->record_info->puser_data->multi_audio_type,
		((len < MAX_PVR_AUDIO_PID) ? len : MAX_PVR_AUDIO_PID));

	if(need_malloc)
		_pvr_mgr_free(record_item->record_info->puser_data);
  	
	return ret;
}

RET_CODE _pvr_mgr_set_ciplus_uri(ppvr_mgr_list_item record_item, record_ciplus_uri_item *item)
{
	RET_CODE ret = RET_SUCCESS;
 	ppvr_mgr_active_record record = NULL;
	ppvr_mgr_user_data user_data = NULL;
	BOOL need_malloc = FALSE;
	UINT32 user_data_len;
	REC_ENG_INFO item_info;
	
	pvr_return_val_if_fail(((record_item != NULL) && (record_item->record_info != NULL)), RET_FAILURE);

	user_data = record_item->record_info->puser_data;
	record = _pvr_get_record_bypath(record_item->record_dir_path);
	
	if((record != NULL) && (record->r_handle != 0))
	{
		pvr_eng_get_record_info(0, record_item->record_dir_path, &item_info);
		_pvr_list_trans_eng_info(&record_item->record_info->record, &item_info);
	}
	
	if(user_data == NULL)
	{
		need_malloc = TRUE;
		_pvr_mgr_malloc(user_data, sizeof(pvr_mgr_user_data), 1);
		pvr_eng_get_user_data(0, record_item->record_dir_path, user_data, &user_data_len);
	}

	if(user_data->uri_num < PVR_MAX_URI_NUM)
	{
		MEMCPY(user_data->uri_array[user_data->uri_num].ciplus_key_uri, (UINT8 *)item->uDetail, PVR_CIPLUS_URI_LEN);
		user_data->uri_array[user_data->uri_num].uri_ptm = item->ptm;
		user_data->uri_num++;
	}
	else
	{
		return RET_FAILURE;
	}

	/* limitation priority of copy type: copy never > copy no more > copy once > copy freely */
	if ((user_data->copy_type == PVR_COPY_NO_MORE) && (item->copy_type == PVR_COPY_ONE_GENR))
	{
		/* no need to update */
	}
	else if ((user_data->copy_type == PVR_COPY_ONE_GENR) && (item->copy_type == PVR_COPY_NO_MORE))
	{
		user_data->copy_type = item->copy_type;
	}
	else if (item->copy_type > user_data->copy_type)
	{
		user_data->copy_type = item->copy_type;
	}

	if((item->retention_limit != 0) &&
		((user_data->retention_limit == 0) ||(item->retention_limit <  user_data->retention_limit)) )
	{
		 user_data->retention_limit = item->retention_limit;
	}

	if(user_data->copy_type == PVR_COPY_NEVER)
	{
		item_info.copy_control = 3;
		item_info.retention_limit = user_data->retention_limit;
		pvr_eng_set_record_info(0, record_item->record_dir_path, &item_info); //trans RL to eng info
	}
	
	ret = pvr_eng_set_user_data(0, record_item->record_dir_path, user_data, sizeof(pvr_mgr_user_data));

	if(need_malloc)
		_pvr_mgr_free(user_data);
	
	return ret;
}

INT8 _pvr_mgr_get_ciplus_uri(ppvr_mgr_list_item record_item, UINT32 ptm, record_ciplus_uri_item *uri)
{
	//get the left URI of the ptm! return URI index
	INT8 ret = -1;
	ppvr_mgr_user_data user_data = NULL;
	INT16 i = 0;
	
	pvr_return_val_if_fail(((record_item != NULL) && (record_item->record_info != NULL)), RET_FAILURE);

	user_data = record_item->record_info->puser_data;

	if((record_item->record_info->record.is_reencrypt) && (user_data != NULL))
	{		
		//compare time
		for(i=(user_data->uri_num-1); i>=0; i--)
		{
			if(user_data->uri_array[i].uri_ptm <= ptm)
			{
				MEMCPY(uri->uDetail, user_data->uri_array[i].ciplus_key_uri, PVR_CIPLUS_URI_LEN);
				uri->ptm = user_data->uri_array[i].uri_ptm;
				uri->copy_type = user_data->copy_type;
				uri->retention_limit = user_data->retention_limit;
				ret = i;
				break;
			}
		}
	}

	return ret;
}


